package com.pshcp.service;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.framework.common.config.CustomConf;
import com.framework.util.SystemUtil;
import com.pshcp.common.tool.FileTool;
import com.pshcp.domain.dto.PatientDTO;
import com.pshcp.domain.model.Patient;
import com.pshcp.domain.model.PatientQrcode;
import com.pshcp.mapper.PatientMapper;
import com.github.pagehelper.PageHelper;
import com.framework.base.PageList;
import com.framework.tool.CommonTool;
import com.pshcp.common.enums.CommonStatusEnum;
import com.pshcp.mapper.PatientQrcodeMapper;
import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 患者就诊人表 服务实现类
 * </p>
 *
 * @author auto generator
 * @since 2022-11-02
 */
@Service
public class PatientService {

    @Autowired
    private PatientMapper patientMapper;
    @Autowired
    private CustomConf customConf;
    @Autowired
    private PatientQrcodeMapper patientQrcodeMapper;

    public Long queryPatient(String patientCardNo){
        return patientMapper.queryPatient(patientCardNo);
    }

    public Patient findByHisId(String hisId) {
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hisPatientId", hisId);
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        // 添加排序
        example.setOrderByClause(" last_handle_time desc");
        List<Patient> patients = patientMapper.selectByExample(example);
        return CollectionUtils.isEmpty(patients) ? null : patients.get(0);
    }

    public Patient getPatientByCardNo(Integer patientCardType, String patientCardNo) {
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("status", CommonStatusEnum.INIT.getCode());
        criteria.andEqualTo("patientCardType", patientCardType);
        criteria.andEqualTo("patientCardNo", patientCardNo);
        List<Patient> list = patientMapper.selectByExample(example);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    public PageList<Patient> pageList(PatientDTO patientDTO) {
        if (patientDTO.getPageNum() != null && patientDTO.getPageSize() != null) {
            PageHelper.startPage(patientDTO.getPageNum(), patientDTO.getPageSize());
        }
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        if (patientDTO.getStatus() != null) {
            criteria.andEqualTo("status", patientDTO.getStatus());
        }
        example.setOrderByClause(" created_time desc");
        List<Patient> list = patientMapper.selectByExample(example);
        return CommonTool.buildPageList(list);
    }

    public List<Patient> list(PatientDTO patientDTO) {
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        if (patientDTO.getStatus() != null) {
            criteria.andEqualTo("status", patientDTO.getStatus());
        }
        if (patientDTO.getPatientUserId() != null) {
            criteria.andEqualTo("patientUserId", patientDTO.getPatientUserId());
        }
        if (patientDTO.isOnlyBindHis()) {
            criteria.andIsNotNull("hisPatientId");
        }
        example.setOrderByClause(" created_time desc");
        return patientMapper.selectByExample(example);
    }

    public List<Patient> select(Patient patient) {
        return patientMapper.select(patient);
    }

    public int insert(Patient patient) {
        patient.setId(SystemUtil.getId());
        patient.setStatus(CommonStatusEnum.INIT.getCode());
        patient.setCreatedTime(new Date());
        return patientMapper.insert(patient);
    }

    public int update(Patient patient) {
        patient.setUpdateTime(new Date());
        return patientMapper.updateByPrimaryKeySelective(patient);
    }

    public Patient findById(Long id) {
        return patientMapper.selectByPrimaryKey(id);
    }

    public List<Patient> findByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", ids);
        return patientMapper.selectByExample(example);
    }

    public int delById(Long id) {
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", id);

        Patient patient = new Patient();
        patient.setStatus(CommonStatusEnum.DEL.getCode());
        return patientMapper.updateByExampleSelective(patient, example);
    }

    /**
     * 更新其他就诊人默认值
     * @param patientUserId
     * @param id
     * @return
     */
    public int updateDefault(Long patientUserId, Long id) {
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("patientUserId", patientUserId);
        criteria.andNotEqualTo("id", id);

        Patient patient = new Patient();
        patient.setIsDefault(0);
        return patientMapper.updateByExampleSelective(patient, example);
    }

    /**
     * 处理用户、患者最后操作时间
     */
    public void updatePatientLastHandleTime(Long patientUserId){
        // 修改用户下患者最后操作时间
        Example example = new Example(Patient.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("patientUserId", patientUserId);

        Patient patient = new Patient();
        patient.setLastHandleTime(new Date());
        patientMapper.updateByExampleSelective(patient, example);
    }

    /**
     * 生成就诊卡二维码
     */
    public PatientQrcode createQrCode(String patientCardNo){
        // 查询是否有数据
        PatientQrcode patientQrcode = queryPatientQrcode(patientCardNo);
        if(patientQrcode != null){
            patientQrcode.setFileOne(customConf.getFileUrl() + patientQrcode.getFileOne());
            patientQrcode.setFileTwo(customConf.getFileUrl() + patientQrcode.getFileTwo());
            return patientQrcode;
        }
        // 获取路径前缀
        String prefix = FileTool.getPrefix(5);
        // 生成二维码
        String fileOne = createQrCode(prefix, patientCardNo);
        // 生成条形码
        String fileTwo = createBarCode(prefix, patientCardNo);
        if(fileOne == null || fileTwo == null){
            return null;
        }
        // 添加数据
        PatientQrcode patientQrcodeNew = new PatientQrcode();
        patientQrcodeNew.setPatientCardNo(patientCardNo);
        patientQrcodeNew.setFileOne(fileOne);
        patientQrcodeNew.setFileTwo(fileTwo);
        patientQrcodeMapper.insert(patientQrcodeNew);
        // 处理返回值
        patientQrcodeNew.setFileOne(customConf.getFileUrl() + patientQrcodeNew.getFileOne());
        patientQrcodeNew.setFileTwo(customConf.getFileUrl() + patientQrcodeNew.getFileTwo());
        return patientQrcodeNew;
    }

    // 查询是否存在数据
    public PatientQrcode queryPatientQrcode(String patientCardNo){
        Example example = new Example(PatientQrcode.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("patientCardNo", patientCardNo);
        List<PatientQrcode> lstData = patientQrcodeMapper.selectByExample(example);
        return CollectionUtils.isEmpty(lstData) ? null : lstData.get(0);
    }

    // 生成二维码
    public String createQrCode(String prefix, String content){
        try{
            String path = "/" + prefix + "/" + content + "one.png";
            String filePath = customConf.getUploadFilePath() + path;
            // 使用hutool工具包生成二维码
            File hutoolFile = new File(filePath);
            QrConfig qrConfig = QrConfig.create();
            qrConfig.setBackColor(Color.WHITE);
            qrConfig.setForeColor(Color.BLACK);
            QrCodeUtil.generate(content, qrConfig, hutoolFile);
            return path;
        }catch (Exception e){
            return null;
        }
    }

    // 生成条形码
    public String createBarCode(String prefix, String content){
        try {
            String path = "/" + prefix + "/" + content + "two.png";
            String filePath = customConf.getUploadFilePath() + path;
            File file = new File(filePath);
            OutputStream ous = new FileOutputStream(file);
            if(ous == null){
                return null;
            }
            //选择条形码类型(好多类型可供选择)
            Code128Bean bean = new Code128Bean();
            bean.setFontSize(0);
            //设置长宽
            final double moduleWidth = 0.4;
            final int resolution = 130;
            bean.setModuleWidth(moduleWidth);
            bean.doQuietZone(false);
            String format = "image/png";
            // 输出流
            BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format, resolution, BufferedImage.TYPE_BYTE_BINARY, false, 0);
            //生成条码
            bean.generateBarcode(canvas, content);
            canvas.finish();
            return path;
        }catch (IOException e) {
            return null;
        }
    }
}
